package com.example.onlinemonitoring.comCenter;

import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.Util.IEEE754Utils;
import com.example.onlinemonitoring.dao.DlqjchistoryTestMapper;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.DlqjchistoryTest;
import com.example.onlinemonitoring.model.Dlqjcsensor;
import com.example.onlinemonitoring.serviceImpl.DlqjcsensorServiceImpl;

import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import tk.mybatis.mapper.entity.Example;
import org.springframework.context.annotation.Scope;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service("dlq61850Com")
@Scope("prototype")
public class Dlq61850Com extends CommPortManager {
    @Autowired
    private DlqjcsensorServiceImpl dlqserviceimpl;
    @Autowired
    private DlqjchistoryTestMapper dlqjchistorytestmapper;
    public float[] x = new float[6];
    public float[] y = new float[6];
    public String[] type = { "A相", "B相", "C相" };
    public String[] cmdtype = { "01", "02", "03" };
    public String[] statetype = { "00", "01", "02", "03", "04" };
    public Long id = 0L;
    private boolean tripopen = true;
    DlqjchistoryTest currdlq = new DlqjchistoryTest();

    // @Override
    // protected void myInit() {
    // if(ad.getBrand().split(",")[0].equals("1")){//开启行程
    // tripopen = true;
    // }else{
    // tripopen = false;
    // }
    // }
    @Override
    public void receiveData(String str) {
        setText("收到sanway请求：" + str);
        if (str.length() < 16) {
            return;
        }
        switch (str.substring(4, 6)) {
            case "80":
                getSystemInfo(str);
                break;
            case "81":
                getSpectrogram(str);
                break;
            case "82":
                getNormalData(str);
                break;
            case "F1":
                deleteFirst(str);
                break;
            default:
                break;
        }
    }

    private void deleteFirst(String str) {
        if (str.substring(10, 12).equals("01")) {
            dlqjchistorytestmapper.deleteByPrimaryKey(currdlq);
            setText("已完成图谱上传");
        } else {
            setText("图谱上传失败！");
        }
        Send(str);
    }

    private void getNormalData(String str) {
        String s = "", s1 = "";
        Dlqjcsensor dlq = new Dlqjcsensor();
        dlq.setStationid(ad.getStationid());
        dlq.setDevicegroup(ad.getDevicegroup());
        dlq.setDeviceaddr(parseHex4(str.substring(2, 4)) + 6010);
        dlq.setCmd(67);
        dlq = dlqserviceimpl.getModel(dlq);
        if (dlq == null) {
            s = "7F" + str.substring(2, 4) + "F2";
        } else {
            s = "7F" + str.substring(2, 4) + "F2";
            if (isnull(dlq.getLastastoragestate()) == 1) {
                s1 += "01";
            } else {
                s1 += "00";
            }
            if (dlq.getLastastate() == 1) {
                s1 += "00";
            } else {
                s1 += "01";
            }
            s1 += isnull(dlq.getLastcommunicationstatus()) == 0 ? "00" : "01";// [1]-储能电机工作状态(1字节)（0 未储能，1储能） 1,1,1,14
            s1 += !isnull(dlq.getLastalarmmessage()).contains("卡涩") ? "00" : "01";
            s1 += !isnull(dlq.getLastalarmmessage()).contains("卡滞") ? "00" : "01";
            s1 += !isnull(dlq.getLastalarmmessage()).contains("偏离") ? "00" : "01";
            s1 += IEEE754Utils.singleToHex(Math.abs(isnull(dlq.getLastaacurrent()) - isnull(dlq.getLastaccurrent())));
            s1 += IEEE754Utils.singleToHex(isnull(dlq.getLastaacurrent()));
            s1 += String.format("%04x", isnull(dlq.getAcount()));
            s1 += String.format("%02x", 100 - dlq.getLifetime().intValue());
            if (tripopen) {
                Dlqjcsensor record = new Dlqjcsensor();
                {
                    Example example = new Example(Dlqjcsensor.class);
                    Example.Criteria criteria = example.createCriteria();
                    criteria.andEqualTo("stationid", ad.getStationid());
                    // criteria.andEqualTo("devicegroup",ad.getDevicegroup());
                    criteria.andEqualTo("deviceaddr", parseHex4(str.substring(2, 4)) + 6010);
                    criteria.andEqualTo("cmd", 64);
                    criteria.andEqualTo("laststate", 2);
                    record = dlqserviceimpl.selectOneByExample(example);
                    s1 += IEEE754Utils.singleToHex(record.getLastspeed());
                }
                {
                    Example example = new Example(Dlqjcsensor.class);
                    Example.Criteria criteria = example.createCriteria();
                    criteria.andEqualTo("stationid", ad.getStationid());
                    // criteria.andEqualTo("devicegroup",ad.getDevicegroup());
                    criteria.andEqualTo("deviceaddr", parseHex4(str.substring(2, 4)) + 6010);
                    criteria.andEqualTo("cmd", 64);
                    criteria.andEqualTo("laststate", 1);
                    record = dlqserviceimpl.selectOneByExample(example);
                    s1 += IEEE754Utils.singleToHex(record.getLastspeed());
                }

            }
        }
        s += String.format("%04x", s1.length() / 2) + s1;
        s += CRC16.calcCrc16(s);
        setText("61850正在请求常态数据");
        Send(s);
    }

    private void getSpectrogram(String str) {
        String s = "", s1 = "";
        DlqjchistoryTest dlq = new DlqjchistoryTest();
        Example example = new Example(DlqjchistoryTest.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("stationid", dlq.getStationid());
        // criteria.andEqualTo("devicegroup",dlq.getDevicegroup());
        criteria.andEqualTo("deviceaddr", parseHex4(str.substring(2, 4)) + 6010);
        example.orderBy("datatime").asc();
        RowBounds rb = new RowBounds(0, 1);
        List<DlqjchistoryTest> dlqlist = dlqjchistorytestmapper.selectByExampleAndRowBounds(example, rb);
        if (dlqlist.size() == 0) {
            s = "7F" + str.substring(2, 4) + "F1";
        } else {
            dlq = dlqlist.get(0);
            s = "7F" + str.substring(2, 4) + "F1";
            s1 += cmdtype[dlq.getCmd() - 64];
            s1 += statetype[dlq.getLaststate()];
            x[0] = dlq.getT0time();
            x[1] = dlq.getT1time();
            x[2] = dlq.getT2time();
            x[3] = dlq.getT3time();
            x[4] = dlq.getT4time();
            x[5] = dlq.getT5time();
            y[0] = dlq.getI0current();
            y[1] = dlq.getI1current();
            y[2] = dlq.getI2current();
            y[3] = dlq.getI3current();
            y[4] = dlq.getI4current();
            y[5] = dlq.getI5current();
            float[][] xy = { { x[0], y[0] }, { x[1], y[1] }, { x[2], y[2] }, { x[3], y[3] }, { x[4], y[4] },
                    { x[5], y[5] } };
            float[][] res = bezier(xy, 100);
            for (int i = 0; i < 100; i++) {
                Float f = res[i][1] * 100;
                s1 += String.format("%04x", f.shortValue());

            }
            // for(int i = 0;i<100;i++){
            // if(i>x[5]) {
            // s1+=String.format("%04x", 0);
            // } else {
            // int val = lagrange(i).intValue();
            // if(val<0){
            // s1+=String.format("%04x", 0);
            // }else{
            // s1+=String.format("%04x", val);
            // }
            // }
            // }
            currdlq = dlq;
        }
        s += String.format("%04x", s1.length() / 2) + s1;
        s += CRC16.calcCrc16(s);
        setText("61850正在请求谱图数据");
        Send(s);
    }

    private void getSystemInfo(String str) {
        String s = "", s1 = "";
        DlqjchistoryTest dlqhistest = new DlqjchistoryTest();
        Example example = new Example(DlqjchistoryTest.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("stationid", dlqhistest.getStationid());
        // criteria.andEqualTo("devicegroup",dlqhistest.getDevicegroup());
        criteria.andEqualTo("deviceaddr", parseHex4(str.substring(2, 4)) + 6010);
        example.orderBy("datatime").asc();
        RowBounds rb = new RowBounds(0, 1);
        List<DlqjchistoryTest> dlqlist = dlqjchistorytestmapper.selectByExampleAndRowBounds(example, rb);
        if (dlqlist.size() == 0) {
            s = "7F" + str.substring(2, 4) + "F0";
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat("YYYYMMddHHmmss");
            Dlqjcsensor dlq = new Dlqjcsensor();
            dlq.setStationid(ad.getStationid());
            dlq.setDevicegroup(ad.getDevicegroup());
            dlq.setDeviceaddr(parseHex4(str.substring(2, 4)) + 6010);
            dlq.setCmd(67);
            dlq = dlqserviceimpl.getModel(dlq);
            if (dlq == null) {
                s = "7F" + str.substring(2, 4) + "F0";
            } else {
                s = "7F" + str.substring(2, 4) + "F0";
                s1 += IEEE754Utils.singleToHex(1.2f);// 本要求设为1.2。 float(4字节）
                s1 += IEEE754Utils.singleToHex(1.001f);// [4]-厂家内部使用的版本号（默认1.001） float(4字节）
                s1 += String.format("%04x", 2);// [5]-应与文件名的谱图类型编码一致（默认02）。Short(2字节)参见备注1：
                try {
                    s1 += sdf.format(HexUtil.todate(new Date()));// 生成谱图的时间（发送时的时间YYYYMMDDhhmmss20211029030303）8字节
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                s1 += String.format("%02x", 1);// [7]-是否测试文件（默认01）char(1字节)
                StringBuffer sbu = new StringBuffer();
                char[] chars = dlq.getPointname().toCharArray();
                String strs = "00000000000000000000000000000000000000000000000000000000000000";
                for (int i = 0; i < chars.length; i++) {
                    int chnum = (int) chars[i];
                    if (chnum <= 255) {
                        strs += String.format("%02x", (int) chars[i]);
                    } else {
                        strs += String.format("%04x", (int) chars[i]);
                    }
                }
                strs += "00";
                s1 += strs.substring(strs.length() - 64);// [8]-被监测设备名称(默认00000000000）32字节
                s1 += String.format("%02x", 2);// [9]-断路器控制机构（默认02）char(1字节）参加备注2：
                // s+=String.format("%02x",
                // list.get(0).getLaststate());//[10]-波形类型（分闸00、合闸02。储能03.开断波形04）char 1字节
                if (dlqlist.get(0).getLaststate() == 3 || dlqlist.get(0).getLaststate() == 4) {
                    s1 += IEEE754Utils.singleToHex(3f);// [11]-数据点的时间间隔，用于绘制X轴（默认1）float(4字节）
                } else {
                    s1 += IEEE754Utils.singleToHex(1f);// [11]-数据点的时间间隔，用于绘制X轴（默认1）float(4字节）
                }
                s1 += IEEE754Utils.singleToHex(0.1f);// 数据点的最大值，用于绘制Y轴（默认0.1）float(4字节）
                s1 += String.format("%02x", 0);// [13]-X轴单位（默认0代表ms）char(1字节)
                s1 += String.format("%02x", 0);// [14]-Y轴单位(默认0代表A)char(1字节)
                s1 += String.format("%04x", 100);// [15]-数据点数k)t(2字节）
                // s+=String.format("%02x", 1);//[16]-储能电机工作状态（0 未储能，1储能）
            }
        }

        s += String.format("%04x", s1.length() / 2) + s1;
        s += CRC16.calcCrc16(s);
        setText("61850正在请求配置数据");
        Send(s);
    }

    Float lagrange(int test) {
        Float[] l = new Float[100];

        Float re = 0f;
        for (int i = 0; i < 100; i++) {
            l[i] = 1f;
        }
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 6; j++) {
                if (j != i) {
                    l[i] *= (test - x[j]) / (x[i] - x[j]);
                }
            }
            re += l[i] * y[i];
        }
        return re * 100;
    }

    Float lagrange1(int test) {
        Float[] l = new Float[100];

        Float re = 0f;
        for (int i = 0; i < 100; i++) {
            l[i] = 1f;
        }
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (j != i) {
                    l[i] *= (test - x[j]) / (x[i] - x[j]);
                }
            }
            re += l[i] * y[i];
        }
        return re * 100;
    }
}
